package ee.reliability.tool.parser;

import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import ee.reliability.tool.parser.Period.PeriodType;
import ee.reliability.tool.util.CalendarHelper;

public class FileParser {

	private final List<Period> periodList = new LinkedList<>();

	public FileParser(Workbook workbook) {
		Period period = null;
		for (int sheetId = workbook.getNumberOfSheets() - 1; sheetId >= 0; sheetId--) {
			Sheet sheet = workbook.getSheetAt(sheetId);
			for (Row row : sheet){
				if(!isValidRow(row))
					continue;
				Calendar date = getDate(row);
				if(CalendarHelper.getInstance().isWorkDay(date.getTime())){
					PeriodType todayState = isSick(row) ? PeriodType.SICK : PeriodType.WORKING;

					if(period == null || period.getPeriodType() != todayState || period.getMax().get(Calendar.YEAR) != date.get(Calendar.YEAR))
						period = startPeriod(row, date, todayState);
					else{
						period.addHours(getHours(row, todayState));
						period.setMax(date.getTime());
					}
				}
			}
		}

		for (Period p : getPeriodList())
			System.out.printf("{%s - %s} : %7s : %7.2f\n", p.getMinDate(), p.getMaxDate(), p.getPeriodType(), p.getRealHours());
	}

	public FileParser(Scanner scanner) {
		while (scanner.hasNextLine()) {
			String line = scanner.nextLine();
			String[] items = line.split(" +");
			if(items.length != 2)
				throw new RuntimeException("Bad file format");

			Period period = new Period();
			period.setPeriodType(PeriodType.valueOf(items[0].trim()));
			period.setRealHours(Double.parseDouble(items[1].trim()));
			periodList.add(period);
		}
	}

	private Period startPeriod(Row row, Calendar date, PeriodType todayState) {
		Period period = new Period();
		period.setMin(date.getTime());
		period.setMax(date.getTime());
		period.setPeriodType(todayState);
		period.setRealHours(getHours(row, todayState));
		getPeriodList().add(period);
		return period;
	}


	@SuppressWarnings("deprecation")
	private double getHours(Row row, PeriodType todayState) {
		double time = 0;
		switch (todayState) {
		case WORKING:
			Cell cellWithHours = row.getCell(9);
			if (cellWithHours != null && cellWithHours.getCellType() != Cell.CELL_TYPE_BLANK && cellWithHours.getCellType() != Cell.CELL_TYPE_STRING)
				time = cellWithHours.getDateCellValue().getHours() + (double)cellWithHours.getDateCellValue().getMinutes() / 60;
			break;
		case SICK:
			time = CalendarHelper.getInstance().getWorkHoursInDay(getDate(row).getTime());
			break;
		}
		return time;
	}


	private Calendar getDate(Row row) {
		Calendar c = Calendar.getInstance();
		c.clear();
		c.setTime(row.getCell(2).getDateCellValue());
		return c;
	}

	private boolean isValidRow(Row row) {
		Cell cellWithDate = row.getCell(2);
		if(cellWithDate == null || cellWithDate.getCellType() != Cell.CELL_TYPE_NUMERIC)
			return false;
		return true;
	}

	private boolean isSick(Row row){
		Cell cell = row.getCell(3);
		if(cell != null && cell.toString().equals("H"))
			return true;
		return false;
	}

	public List<Period> getPeriodList() {
		return periodList;
	}

}
